package it.crosato.stage.server.model.comparison;

import it.crosato.stage.shared.objects.InvariantsGroup;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;
import java.util.Vector;
import java.util.logging.Logger;

public class InvariantsCalculator {

	/**
	 * Utilizza lo strumento 4ti2 per ottenere i T-invarianti minimali di una rete
	 * di Petri
	 * @param A la matrice incidenza della rete di Petri
	 * @param sid id della sessione. Serve per idendificare i files di 4ti2 relativi
	 * ad un particolare utente
	 * @param path il percorso dell'applicazione. Serve per salvare i files di 4ti2
	 * all'interno dell'applicazione
	 * @return l'insieme dei T-invarianti minimali di della rete di Petri
	 */
	public static InvariantsGroup getInvariants(int[][] A, String sid, String path) {
		InvariantsGroup invariantsGroup = null;
		try {
			FileOutputStream inputFile = new FileOutputStream(path + "4ti2/" + sid + "-incidence_matrix.mat");
			PrintStream Output = new PrintStream(inputFile);
			Output.println(A.length + " " + A[0].length);
			for (int i = 0; i < A.length; i++) {
				for (int j = 0; j < A[0].length; j++) {
					Output.print(A[i][j] + " ");
				}
				Output.println();
			}
			try {
				String dir = System.getProperty("user.home") + "/";
				Process p = Runtime.getRuntime().exec(dir + "4ti2/linux_x86/hilbert " +
						path + "4ti2/" + sid + "-incidence_matrix");
				p.waitFor();
				Scanner Input = new Scanner(new FileInputStream(path + "4ti2/" + sid + "-incidence_matrix.hil"));
				invariantsGroup = new InvariantsGroup();
				String line = Input.nextLine();
				int numberOfInvariants = Integer.parseInt((line.split(" ")[0]));
				int numberOfReactions = Integer.parseInt((line.split(" ")[1]));
				Input.nextLine(); // riga vuota
				for (int i = 0; i < numberOfInvariants; i++) {
					line = Input.nextLine();
					line = line.substring(1); // elimina spazio iniziale
					line = line.replace("  ", " "); // elimina doppi spazi separatori
					String[] invariantString = line.split(" ");
					Vector<Integer> invariant = new Vector<Integer>();
					for (int j = 0; j < numberOfReactions; j++) {
						invariant.add(Integer.parseInt(invariantString[j]));
					}
					invariantsGroup.addInvariant(invariant);
				}
			}
			catch (InterruptedException e2) {
				Logger.getLogger("mylog").info(e2.toString());
			}
		}
		catch (IOException e1) {
			Logger.getLogger("mylog").info(e1.toString());
		}
		try {
			Runtime.getRuntime().exec("rm " + path + "4ti2/" + sid + "-incidence_matrix.mat");
			Runtime.getRuntime().exec("rm " + path + "4ti2/" + sid + "-incidence_matrix.hil");
		}
		catch(IOException ioe) {
			Logger.getLogger("mylog").info(ioe.getMessage());
		}
		return invariantsGroup;
	}
}
